
import java.io.IOException;
import java.net.InetSocketAddress;
import java.nio.ByteBuffer;
import java.nio.channels.SocketChannel;
import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.List;
import java.util.Scanner;

public class SocketClientNIO {

    public static void main(String[] args) throws Exception {
        try {
            final SocketChannel client = SocketChannel.open();
            client.configureBlocking(false);
            client.connect(new InetSocketAddress("127.0.0.1", 9999));
            if (client.finishConnect()) {
                handleWrite(client);
                handleRead(client);
            } else {
                System.out.println("连接服务器失败");
            }
        } catch (
                Exception e) {
            System.out.println("连接异常");
            e.printStackTrace();
        }
    }

    private static void handleRead(SocketChannel client) throws IOException {
        ByteBuffer byteBuffer = ByteBuffer.allocate(4096);
        while (true) {
            int read = client.read(byteBuffer);
            if (read > 0) {
                //标记缓冲区字节的最后一个位置，并将指针移到起始位置
                byteBuffer.flip();
                String s = new String(
                        byteBuffer.array(),
                        byteBuffer.position(),
                        byteBuffer.limit(),
                        StandardCharsets.UTF_8
                );
                if (byteBuffer.hasRemaining()) {
                    System.out.println("服务器发来消息：" + s);
                }
                byteBuffer.clear();
            } else if (read == 0) {
                //读到为0的话，不需要处理，直接跳出本次handleRead
                continue;
            } else {
                //-1可能客户端close_wait， 读到小于0的话次数超过10次，,关闭client
                System.out.println("read:" + read);
                client.close();
                break;
            }

        }
    }

    private static void handleWrite(SocketChannel client) {
        ByteBuffer buffer = ByteBuffer.allocate(1024);
        final Scanner scanner = new Scanner(System.in);
        Thread thread = new Thread(() -> {
            while (true) {
                try {
                    String s = scanner.nextLine();
                    if ("stop".equals(s.trim())) {
                        try {
                            client.close();
                        } catch (IOException ioException) {
                            ioException.printStackTrace();
                        }

                    }
                    buffer.put(s.getBytes());
                    buffer.flip();
                    while (buffer.hasRemaining()) {
                        client.write(buffer);
                    }
                    buffer.clear();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        });
        thread.start();
    }
}
